package it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.emf.ecore.util.EcoreUtil;

import it.univaq.mancoosi.injectors.systemconfiguration.managers.GConfManager;
import it.univaq.mancoosi.injectors.systemconfiguration.utils.ProcessCommand;
import it.univaq.mancoosi.mancoosimm.File;
import it.univaq.mancoosi.mancoosimm.GConf;
import it.univaq.mancoosi.mancoosimm.MenuEntry;
import it.univaq.mancoosi.mancoosimm.MenuSection;

public class UbuntuGConfManager extends GConfManager {
	
	protected ArrayList<String> allFiles = new ArrayList<String>();
	ArrayList<String> schemas;
	ArrayList<String> gConfFiles;
	protected GConf gconf = factory.createGConf(); 
	
	public static GConfManager getInstance() {
		if (INSTANCE == null)
			INSTANCE = new UbuntuGConfManager();
		return INSTANCE;
	}
	
	@Override
	public void createGConfFromSystem() {
		syncGConfMap();
		syncSchemaMap();
		
		if(UbuntuEnvironmentManager.getInstance().getEnvironment().getGconf() != null){
			this.gconf.getConfFiles().addAll(UbuntuEnvironmentManager.getInstance().getEnvironment().getGconf().getConfFiles());
			this.gconf.getSchemas().addAll(UbuntuEnvironmentManager.getInstance().getEnvironment().getGconf().getSchemas());
		}
		
		try {
			schemas = getSchemaFile();
			gConfFiles = getGconfFile();

			gconf.setEnv(UbuntuEnvironmentManager.getInstance().getEnvironment());
			
			if  (schemas.size() > 0) {
				for(int i=0; i<schemas.size(); i++){	
					java.io.File file = new java.io.File("/usr/share/gconf/schemas/"+schemas.get(i));
//					java.io.File file = new java.io.File("/home/martina/prova/"+schemas.get(i));
					if(file.exists()){
						if (!existsSchema(file.getName())) {
							File modelFile = UbuntuFileSystemManager.getInstance().createFile("/usr/share/gconf/schemas/"+schemas.get(i));
//							File modelFile = UbuntuFileSystemManager.getInstance().createFile("/home/martina/prova/"+schemas.get(i));
							this.gconf.getSchemas().add(modelFile);	
							this.schemaMap.put(file.getName(), modelFile);
						}
					}
				}
			}
			
			if (gConfFiles.size() > 0){
				for(int i=0; i<gConfFiles.size(); i++){
					java.io.File file2 = new java.io.File(gConfFiles.get(i));
					if(file2.exists()){
						if (!existsGConf(file2.getPath())) {
							File modelFile2 = UbuntuFileSystemManager.getInstance().createFile(gConfFiles.get(i));
							this.gconf.getConfFiles().add(modelFile2);
							this.gconfMap.put(file2.getPath(), modelFile2);
						}
					}
				}
			}

		} catch (Exception err) {
			err.printStackTrace();
		}
	}
	
	protected ArrayList<String> getSchemaFile(){
		ArrayList<String> result = new ArrayList<String>();
		String line;

		try {
			String[] cmd = {"/bin/sh","-c","ls --time-style=long-iso -l /usr/share/gconf/schemas | awk '{print $8}'"};
			BufferedReader input = ProcessCommand.getInstance().getResult(cmd);	

			line = input.readLine(); 
			while ((line = input.readLine()) != null) {
				result.add(line);
			}

			input.close();

		} catch (Exception err) {
			err.printStackTrace();
		}

		return result;			
	}
	
	protected ArrayList<String> getGconfFile(){
		
		ArrayList<String> result = new ArrayList<String>();
		String output;
		
		try {
			String[] cmd = {"/bin/sh", "-c","echo ${HOME}"};
			BufferedReader input = ProcessCommand.getInstance().getResult(cmd);	

			output = input.readLine();
			
			getFiles(output + "/.gconf");
			
			if(!output.equals("/root")){
				getFiles("/root/.gconf");
			}
			
			input.close();
			
			}catch (Exception e ) {
				e.printStackTrace();
			}
			
			result = allFiles;
			return result;
	}
	
	public void getFiles (String dir) {

		java.io.File file = new java.io.File(dir);
		java.io.File[] listFiles = file.listFiles();
		for (java.io.File f : listFiles) {
			if (!f.isDirectory()) {
				if (f.getPath().endsWith("%gconf.xml"))
					allFiles.add(f.getPath());
			}
			else getFiles(f.getPath());
		}
	}


	@Override
	public void synchronize() throws IOException {
		createGConfFromSystem();
		
		//synchronize gconf files		
		int gconfInTheSystem = gConfFiles.size();		
		if(((this.gconfMap.size()) != gconfInTheSystem)){
			Iterator<File> iterator = this.gconfMap.values().iterator();
			while (iterator.hasNext()) {
				File curr = iterator.next();
				if (isMissingGConfInTheSystem(curr.getLocation())) {
					this.gconfMap.remove(curr);
					EcoreUtil.delete(curr);
					UbuntuFileSystemManager.getInstance().deleteFile(curr);
				}
			}
		}
		
		//synchronize schema files
		int schemasInTheSystem = schemas.size();		
		if(((this.schemaMap.size()) != schemasInTheSystem)){		
			Iterator<File> iterator2 = this.schemaMap.values().iterator();
			while (iterator2.hasNext()) {
				File curr = iterator2.next();
				if (isMissingSchemaInTheSystem(curr.getName())) {
					this.schemaMap.remove(curr);
					EcoreUtil.delete(curr);
					UbuntuFileSystemManager.getInstance().deleteFile(curr);
				}
			}
		}
	}
	
//	public int countSchemaFiles() throws IOException {
//		String line;
//
//		Process p;
//		BufferedReader input;
//		int n = 0;
//		try {
//			String[] cmd = {"/bin/sh","-c","ls --time-style=long-iso -l /usr/share/gconf/schemas | wc | awk '{print $1}'"};
//			p = Runtime.getRuntime().exec(cmd);
//			input = new BufferedReader
//			(new InputStreamReader(p.getInputStream()));
//			
//			line = input.readLine();
//			
//			n = Integer.parseInt (line);
//
//		input.close();			
//		p.destroy();
//		
//		} catch (NumberFormatException e) {
//			e.printStackTrace();
//		}
//		
//		return n;
//	}
	
	public boolean isMissingGConfInTheSystem (String gconfPath) {
		if(UbuntuFileSystemManager.getInstance().getFile(gconfPath) != null){
			return UbuntuFileSystemManager.getInstance().getFile(gconfPath).isIsMissing();
		}else{
			return true;
		}
//		java.io.File file = new java.io.File(gconfPath);
//		return file.exists();
	}
	
	public boolean isMissingSchemaInTheSystem (String schemaName) {	
		if(UbuntuFileSystemManager.getInstance().getFile("/usr/share/gconf/schemas/" + schemaName) != null){
			return UbuntuFileSystemManager.getInstance().getFile("/usr/share/gconf/schemas/" + schemaName).isIsMissing();
		}else{
			return true;
		}
//		java.io.File file = new java.io.File("/usr/share/gconf/schemas/" + schemaName);
//		java.io.File file = new java.io.File("/home/martina/prova/" + schemaName);
//		return file.exists();
	}

	@Override
	public Boolean existsGConf(String gconfPath) {
		return this.gconfMap.containsKey(gconfPath);
	}

	@Override
	public Boolean existsSchema(String schemaName) {
		return this.schemaMap.containsKey(schemaName);
	}
}
